home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / tools / developer-tools / aros / source / exec / signals / src / allocsignal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-16  |  2.6 KB  |  117 lines

  1. /*
  2.     $Id$
  3.     $Log$
  4.     Desc:
  5.     Lang: english
  6. */
  7. #include "exec_intern.h"
  8.  
  9. /*****************************************************************************
  10.  
  11.     NAME */
  12.     #include <clib/exec_protos.h>
  13.  
  14.     __AROS_LH1(BYTE, AllocSignal,
  15.  
  16. /*  SYNOPSIS */
  17.     __AROS_LA(long, signalNum, D0),
  18.  
  19. /*  LOCATION */
  20.     struct ExecBase *, SysBase, 55, Exec)
  21.  
  22. /*  FUNCTION
  23.     Allocate a given signal out of the current task's pool of signals.
  24.     Every task has a set of signals to communicate with other tasks.
  25.     Half of them are reserved for the system and half of them is
  26.     free for general use. Some of the reserved signals (e.g.
  27.     SIGBREAKF_CTRL_C) have a defined behaviour and may be used by user
  28.     code, however.
  29.  
  30.     INPUTS
  31.     signalNum - Number of the signal to allocate or -1 if any signal
  32.             will do.
  33.  
  34.     RESULT
  35.     Number of the signal or -1 if the signal couldn't be allocated.
  36.  
  37.     NOTES
  38.  
  39.     EXAMPLE
  40.  
  41.     BUGS
  42.  
  43.     SEE ALSO
  44.     FreeSignal(), Signal(), Wait()
  45.  
  46.     INTERNALS
  47.  
  48.     HISTORY
  49.     29-10-95    digulla automatically created from
  50.                 exec_lib.fd and clib/exec_protos.h
  51.     17-12-95    digulla Incorporated code by Matthias Fleischner
  52.  
  53. *****************************************************************************/
  54. {
  55.     __AROS_FUNC_INIT
  56.     ULONG *mask;
  57.     ULONG mask1;
  58.  
  59.     /* Protect signal mask against possible task exceptions. */
  60.     Forbid();
  61.  
  62.     /* Get pointer to mask of allocated signal */
  63.     mask=&SysBase->ThisTask->tc_SigAlloc;
  64.  
  65.     /* Get signal */
  66.     if(signalNum<0)
  67.     {
  68.     /* Any signal will do. */
  69.  
  70.     /*
  71.      * To get the last nonzero bit in a number I use a&~a+1:
  72.      * Given a number that ends with a row of zeros  xxxx1000
  73.      * I first toggle all bits in that number     XXXX0111
  74.      * then add 1 to toggle all but the last 0 again XXXX1000
  75.      * and AND this with the original number     00001000
  76.      *
  77.      * And since ~a+1=-a I can use a&-a instead.
  78.      *
  79.      * And to get the last zero bit I finally use ~a&-~a.
  80.      */
  81.     mask1=~*mask&-~*mask;
  82.  
  83.     /* Got a bit? */
  84.     if(mask1)
  85.     {
  86.         /* Allocate and reset the bit */
  87.         *mask|=mask1;
  88.         SysBase->ThisTask->tc_SigRecvd&=~mask1;
  89.  
  90.         /* And get the bit number */
  91.         signalNum=(mask1&0xffff0000?16:0)+(mask1&0xff00ff00?8:0)+
  92.               (mask1&0xf0f0f0f0? 4:0)+(mask1&0xcccccccc?2:0)+
  93.               (mask1&0xaaaaaaaa? 1:0);
  94.     }
  95.     }else
  96.     {
  97.     /* Get a specific signal */
  98.     mask1=1<<signalNum;
  99.  
  100.     /* Check if signal is free */
  101.     if(*mask&mask1)
  102.         /* No. Return */
  103.         signalNum=-1;
  104.     else
  105.     {
  106.         /* It is free. Allocate and reset it. */
  107.         *mask|=mask1;
  108.         SysBase->ThisTask->tc_SigRecvd&=~mask1;
  109.     }
  110.     }
  111.  
  112.     Permit();
  113.  
  114.     return (BYTE)signalNum;
  115.     __AROS_FUNC_EXIT
  116. } /* AllocSignal */
  117.